package com.sj.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sj.common.bean.LocalUser;
import com.sj.common.dto.label.LabelDto;
import com.sj.common.lang.ApiResult;
import com.sj.common.lang.RedisConst;
import com.sj.entity.ArticleLabel;
import com.sj.entity.Label;
import com.sj.entity.User;
import com.sj.interceptor.AuthCheck;
import com.sj.service.ArticleLabelService;
import com.sj.service.LabelService;
import com.sj.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 标签表 前端控制器
 * </p>
 *
 * @author 孙峻
 * @since 2022-03-09
 */
@RestController
@RequestMapping("/label")
@Api(tags = "标签模块")
public class LabelController {

    @Autowired
    private LabelService labelService;

    @Autowired
    private UserService userService;

    @Autowired
    private ArticleLabelService articleLabelService;

    @ApiOperation("强制删除")
    @DeleteMapping("/admin/forceDel/{id}")
    @AuthCheck
    @CacheEvict(cacheNames = {"article-num-data", "article-list", "fix-type"}, keyGenerator = RedisConst.REDIS_SJ_KEY_GENERATOR, allEntries = true)
    public ApiResult forceDel(@PathVariable Integer id){
        // 删除 与该文章的标签关联
        articleLabelService.remove(Wrappers.<ArticleLabel>lambdaQuery().eq(ArticleLabel::getLabelId, id));
        boolean result = labelService.remove(Wrappers.<Label>lambdaQuery().eq(Label::getId, id));
        if (result) {
            return ApiResult.success("删除成功");
        }
        return ApiResult.error("删除失败");
    }

    @DeleteMapping("/admin/del/{id}/{userId}")
    @ApiOperation("管理端删除标签")
    @AuthCheck
    @CacheEvict(cacheNames = {"article-num-data", "article-list", "fix-type"}, keyGenerator = RedisConst.REDIS_SJ_KEY_GENERATOR, allEntries = true)
    public ApiResult delLabel(@PathVariable Integer id, @PathVariable Integer userId) {
        Long count = articleLabelService.lambdaQuery().eq(ArticleLabel::getLabelId, id).count();
        if (count > 0) {
            return ApiResult.error("有文章包含当前标签，不能被删除");
        }
        // 删除 与该文章的标签关联
        articleLabelService.remove(Wrappers.<ArticleLabel>lambdaQuery().eq(ArticleLabel::getLabelId, id));
        boolean result = labelService.remove(Wrappers.<Label>lambdaQuery().eq(Label::getId, id).eq(Label::getUserId, userId));
        if (result) {
            return ApiResult.success("删除成功");
        }
        return ApiResult.error("删除失败");
    }

    @ApiOperation("获取管理端所有标签列表")
    @GetMapping("/admin/list")
    @AuthCheck
    public ApiResult getAdminLabelList(@RequestParam(name = "name", required = false) String name, @RequestParam Integer current, @RequestParam Integer size) {
        IPage<Label> page = new Page(current, size);
        IPage<Label> pageModel = labelService.lambdaQuery().like(Label::getLabelName, name).page(page);
        IPage<LabelDto> resultPage = new Page<>();
        BeanUtil.copyProperties(pageModel, resultPage, "records");
        resultPage.setRecords(pageModel.getRecords().stream().map(temp -> {
            LabelDto labelDto = new LabelDto();
            BeanUtil.copyProperties(temp, labelDto, "user");
            User user = userService.getById(labelDto.getUserId());
            user.setPassword(null);
            labelDto.setUser(user);
            return labelDto;
        }).collect(Collectors.toList()));
        return ApiResult.success(resultPage);
    }

    @GetMapping("/all/name")
    @Cacheable(cacheNames = "all-label-name", keyGenerator = RedisConst.REDIS_SJ_KEY_GENERATOR)
    public ApiResult getAllLabelName() {
        List<Label> list = labelService.lambdaQuery().groupBy(Label::getLabelName).orderBy(true, false, Label::getUpdateTime, Label::getUpdateTime).list();
        list = list.stream().map(temp -> {
            temp.setUserId(null);
            temp.setId(null);
            return temp;
        }).collect(Collectors.toList());
        return ApiResult.success(list);
    }

    @GetMapping("/list")
    @AuthCheck
    public ApiResult getLabelList() {
        User user = LocalUser.getUser();
        List<Label> list = labelService.lambdaQuery().eq(Label::getUserId, user.getId()).list();
        return ApiResult.success(list);
    }

}
